package com.nil.codegen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nil.codegen.bean.DsInfo;
import com.nil.codegen.domain.dto.DataSourceDTO;
import com.nil.codegen.domain.entity.DataSource;
import com.nil.codegen.domain.vo.DbDriverVO;
import com.nil.codegen.enums.DriverTypeEnum;
import com.nil.codegen.exception.BusinessException;
import com.nil.codegen.mapper.DataSourceMapper;
import com.nil.codegen.service.IDataSourceService;
import com.nil.codegen.service.IDbDriverService;
import com.nil.codegen.utils.JDBCUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.SQLException;

@Service
public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSource> implements IDataSourceService {

    @Resource
    private IDbDriverService dbDriverService;

    @Override
    public void create(DataSourceDTO dataSourceDTO) {

        DsInfo dsInfo = BeanUtil.copyProperties(dataSourceDTO, DsInfo.class);

        DbDriverVO driver = dbDriverService.getById(dataSourceDTO.getDriverId());
        dsInfo.setPackageUrl(driver.getLibFileUrl());
        DriverTypeEnum driverType = DriverTypeEnum.getByValue(driver.getType());
        if (driverType == null) {
            throw new BusinessException("未知的驱动类型");
        }
        dsInfo.setDriverType(driverType);
        Connection connection = JDBCUtil.testConnection(dsInfo);
        // 持久化
        DataSource dataSource = BeanUtil.copyProperties(dsInfo, DataSource.class);
        dataSource.setDriverType(driver.getType());
        dataSource.setName(dataSourceDTO.getName());
        checkUnique(dataSource);
        this.save(dataSource);
        try {
            connection.close();
        } catch (SQLException e) {
            throw new BusinessException("连接关闭出现异常, " + e.getMessage());
        }
    }

    /**
     * 唯一性校验
     */
    private void checkUnique(DataSource dataSource) {

        LambdaQueryWrapper<DataSource> w1 = Wrappers.lambdaQuery(DataSource.class)
                .eq(DataSource::getName, dataSource.getName());
        boolean ex1 = exists(w1);
        if (ex1) {
            throw new BusinessException("数据源名称重复");
        }

        LambdaQueryWrapper<DataSource> w2 = Wrappers.lambdaQuery(DataSource.class)
                .eq(DataSource::getHost, dataSource.getHost())
                .eq(DataSource::getPort, dataSource.getPort())
                .eq(DataSource::getDbName, dataSource.getDbName());
        boolean ex2 = exists(w2);
        if (ex2) {
            throw new BusinessException("相同数据源已存在");
        }
    }



}
